<?php
/*
 * License : MIT License (see LICENSE)
 */

include(dirname(__FILE__).'/ds_parser_output.php');

class DSParser {
	
	function parse($file) {
		$this->input = '';
		$out = explode('/', $file);
		$out = explode('.', $out[count($out) - 1]);
		array_pop($out);
		$name = implode('.', $out);
		
		$fp = fopen($file, 'r');
		if(!$fp) {
			die('Can\'t find '.$file);
		}
		while(!feof($fp)) {
			$this->input .= fgets($fp);
		}
		fclose($fp);
		
		$this->_clean();
		
		$this->path = array();
		$this->types = array();
		$this->_parse_type($this->input);
		$output = new DSParserOutput('ds_'.$name.'.php', $this->types);
		$output->make();
	}
	function _clean() {
		$this->input = trim(preg_replace('#\s+#', ' ', $this->input));
	}
	function _start_end($input) {
		$i = 0;
		$begin = $end = $count = $done = 0;
		while($i < strlen($input)) {
			if($input[$i] == '{') {
				if($done == 0) {
					$begin = $i;
					$done = 1;
				}
				$count++;
			}
			elseif($input[$i] == '}') {
				if($done == 1) {
					$count--;
					if($count == 0) {
						$end = $i;
						return array($begin, $end);
					}
				}
				else 
					die('Erreur');
			}
			$i++;
		}
	}
	function _next($input) {
		preg_match('#([^\s^\{}]*)#', trim($input), $match);
		return $match[0];
	}
	function _get_type($name) {
		foreach($this->types as $k => $type)
			if($type['name'] == $name) 
				return $k;
	}
	function _parse_field($input) {
		$type = $this->_next($input);
		$input = trim(substr($input, strlen($type) + 1));
		$data_type = $this->_next($input);
		$input = trim(substr($input, strlen($data_type) + 1));
		$name  = $this->_next($input);
		$register = array(	'name' => $name,
						'type' => $type,
						'data_type' => $data_type);
		$this->types[$this->_get_type(implode('_', $this->path))]['fields'][] = $register;
	}
	function _parse_enum($input) {
		while(strlen($input) > 0) {
			$pos = strpos($input, ';');
			$name = trim(substr($input, 0, $pos));
			$this->types[$this->_get_type(implode('_', $this->path))]['fields'][] = $name;
			$input = trim(substr($input, $pos + 1));
		}
	}
	function _parse_type($input) {
		while(strlen($input) > 0) {
			$next = $this->_next($input);
			if($next == 'data') {
				$input = trim(substr($input, 4));
				$data_name = $this->_next($input);
				$this->path[] = $data_name;
				$name = implode('_', $this->path);
				$this->types[] = array(	'name' => $name, 
									'type' => 'data',
									'fields' => array());
				$input = trim(substr($input, strlen($data_name)));
				$se = $this->_start_end($input);
				$this->_parse_type(trim(substr($input, $se[0] + 1, $se[1] - $se[0] - 1)));
				$input = trim(substr($input, $se[0] + $se[1] + 1));
				array_pop($this->path);
			}
			elseif($next == 'enum') {
				$input = trim(substr($input, 4));
				$enum_name = $this->_next($input);
				$this->path[] = $enum_name;
				$name = implode('_', $this->path);
				$this->types[] = array(	'name' => $name, 
									'type' => 'enum',
									'fields' => array());
				$input = trim(substr($input, strlen($enum_name)));
				$se = $this->_start_end($input);
				$this->_parse_enum(trim(substr($input, $se[0] + 1, $se[1] - $se[0] - 1)));
				$input = trim(substr($input, $se[0] + $se[1] + 1));
				array_pop($this->path);
			}
			else {
				$pos = strpos($input, ';');
				$this->_parse_field(trim(substr($input, 0, $pos)));
				$input = trim(substr($input, $pos + 1));
			}
		}
	}
}
?>